package net.dreamlu.assets;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FilenameUtils;
import org.mozilla.javascript.ErrorReporter;
import org.mozilla.javascript.EvaluatorException;

import com.jfinal.log.Log;
import com.yahoo.platform.yui.compressor.CssCompressor;
import com.yahoo.platform.yui.compressor.JavaScriptCompressor;

/**
 * 压缩合并类
 * @author L.cm
 * email: 596392912@qq.com
 * site:http://www.dreamlu.net
 * @date 2017年3月23日下午8:13:12
 */
public class AssetsCompressor {
	private static final Log log = Log.getLog(AssetsCompressor.class);
	
	/**
	 * 压缩合并css
	 * @param in Reader
	 * @param out Writer
	 * @throws IOException
	 */
	public void compressorCss(Reader in, Writer out) throws IOException {
		// css 换行，默认为不换行
		int linebreakpos = -1;
		CssCompressor css = new CssCompressor(in);
		css.compress(out, linebreakpos);
	}
	
	/**
	 * 压缩合并js
	 * @param in Reader
	 * @param out Writer
	 * @throws IOException
	 */
	public void compressorJs(Reader in, Writer out) throws IOException {
		// css 换行，默认为不换行
		int linebreak = -1;
		// nomunge: 混淆,verbose：显示信息消息和警告,preserveAllSemiColons：保留所有的分号 ,disableOptimizations 禁止优化
		boolean munge = true, verbose = false, preserveAllSemiColons = false, disableOptimizations = false;
		JavaScriptCompressor compressor = new JavaScriptCompressor(in, JsCompressorErrorReporter.defaultErrorReporter);
		compressor.compress(out, linebreak, munge, verbose, preserveAllSemiColons, disableOptimizations);
	}
	
	// css中的url图片正则——感谢Code Life(程式人生)的正则
	private static final Pattern CSS_URL_PATTERN = Pattern.compile("url\\([\\s]*['\"]?((?!['\"]?https?://|['\"]?data:|['\"]?/).*?)['\"]?[\\s]*\\)");
	
	/**
	 * 将css文件里的图片相对路径修改为绝对路径
	 * @param content 内容
	 * @param path 路径
	 * @return String css
	 */
	public String repairCss(String content, String path){
		Matcher m = CSS_URL_PATTERN.matcher(content);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			String url = m.group(1).trim();
			StringBuffer cssPath = new StringBuffer("url(").append(FilenameUtils.getFullPath(path)).append(url).append(")");
			m.appendReplacement(sb, cssPath.toString());
		}
		m.appendTail(sb);
		content = sb.toString();
		return content;
	}
	
	/**
	 * js压缩异常报告
	 * @author L.cm
	 * email: 596392912@qq.com
	 * site:http://www.dreamlu.net
	 * @date 2017年3月23日下午8:06:29
	 */
	private static class JsCompressorErrorReporter implements ErrorReporter {
		private static final ErrorReporter defaultErrorReporter = new JsCompressorErrorReporter();
		private JsCompressorErrorReporter() {}
		
		public void warning(String message, String sourceName, int line, String lineSource, int lineOffset) {
			if (line < 0) {
				log.warn("[WARNING] " + message);
			} else {
				log.warn("[WARNING] " + line + ':' + lineOffset + ':' + message);
			}
		}

		public void error(String message, String sourceName, int line, String lineSource, int lineOffset) {
			if (line < 0) {
				log.error("[ERROR] " + message);
			} else {
				log.error("[ERROR] " + line + ':' + lineOffset + ':' + message);
			}
		}

		public EvaluatorException runtimeError(String message, String sourceName, int line, String lineSource,
				int lineOffset) {
			error(message, sourceName, line, lineSource, lineOffset);
			return new EvaluatorException(message);
		}
	}
}
